package com.demo.dao;

import com.demo.config.LogInit;
import com.demo.config.ProjectSettings;
import com.demo.config.SQLSettings;
import com.demo.constant.DBConstant;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.logging.log4j.Logger;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.net.URL;
import java.util.Properties;


public abstract class BaseDao {

    private static Logger logger = LogInit.getInstance();
    private static final String OR_ADMIN = "xxxxx";
    private static final Properties sqlSettings = SQLSettings.getInstance();
    protected static final Properties projectSettings = ProjectSettings.getInstance();

    /**
     * Open the SqlSession to perform SQL operations
     *
     * @return SqlSession
     */
    public static SqlSession openSession(String environment) {
        try {
            Reader reader = Resources.getResourceAsReader("mybatis.xml");
            Properties properties = getEnvironmentProperties(environment);
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader, environment, properties);
            return sqlSessionFactory.openSession();
        } catch (Exception e) {
            throw new RuntimeException("Failed to open session for " + environment + e);
        }
    }

    /**
     * Get Environment Properties
     *
     * @return SqlSession
     */
    private static Properties getEnvironmentProperties(String environment) {
        Properties properties = new Properties();
        properties.setProperty("HOMER_URL",fetchConnectionString(environment));
        properties.setProperty("HOMER_USERNAME", Encrypt.decryptDecode(DBConstant.getHomerUsername(), DBConstant.getSecredtKey()));
        properties.setProperty("HOMER_PASSWORD", Encrypt.decryptDecode(DBConstant.getHomerPassword(), DBConstant.getSecredtKey()));
        properties.setProperty("HP_URL",fetchConnectionString(environment));
        properties.setProperty("HP_USERNAME", Encrypt.decryptDecode(DBConstant.getHpUsername(), DBConstant.getSecredtKey()));
        properties.setProperty("HP_PASSWORD", Encrypt.decryptDecode(DBConstant.getHpPassword(), DBConstant.getSecredtKey()));
        properties.setProperty("CU_URL",fetchConnectionString(environment));
        properties.setProperty("CU_USERNAME", Encrypt.decryptDecode(DBConstant.getCuUsername(), DBConstant.getSecredtKey()));
        properties.setProperty("CU_PASSWORD", Encrypt.decryptDecode(DBConstant.getCuPassword(), DBConstant.getSecredtKey()));
        properties.setProperty("MAPP_URL",fetchConnectionString(environment));
        properties.setProperty("MAPP_USERNAME", Encrypt.decryptDecode(DBConstant.getMappUsername(), DBConstant.getSecredtKey()));
        properties.setProperty("MAPP_PASSWORD", Encrypt.decryptDecode(DBConstant.getMappPassword(), DBConstant.getSecredtKey()));
        return properties;
    }

    private static String fetchConnectionString(String environment) {
        //先判断是否prod环境cu库
        if (DBConstant.getDATABASE().equalsIgnoreCase("xxxxx")) {
            String orAdminLink = "xxxxx";
            logger.info("Database Connection: " + orAdminLink);
            return orAdminLink;
        } else {
            if (environment.equalsIgnoreCase("HOMER")) {
                environment = "";
            }
            String orAdminLink = OR_ADMIN + DBConstant.getDATABASE() + environment;
            logger.info("Fetch database url from: " + orAdminLink);
            try {
                BufferedReader in = new BufferedReader(new InputStreamReader(new URL(orAdminLink).openStream()));
                String dbConnectionString = in.readLine();
                logger.info("Database Connection: " + dbConnectionString);
                return dbConnectionString;
            } catch (IOException e) {
                throw new RuntimeException("Could not read database url from " + orAdminLink);
            }
        }
    }
}

